package com.ilearn.iodata.iolingo.service.processor;

import com.ilearn.iodata.iolingo.service.GetCollectionService;
import com.ilearn.iodata.iolingo.service.processor.core.api.GenericODataSessionContextAccess;
import org.apache.olingo.commons.api.ex.ODataException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.*;
import org.apache.olingo.server.api.processor.*;
import org.apache.olingo.server.api.uri.UriInfo;


public final class GenericODataRequestProcessor
        implements PrimitiveValueProcessor, PrimitiveCollectionProcessor,
        CountEntityCollectionProcessor, EntityProcessor, EntityCollectionProcessor
{
    private final GenericODataSessionContextAccess context;
    private GenericProcessorFactory factory;
    private GetCollectionService getCollectionService;

    public GenericODataRequestProcessor(final GenericODataSessionContextAccess context,GetCollectionService getCollectionService) {
        super();
        this.context = context;
        this.getCollectionService = getCollectionService;
    }

    @Override
    public void init(final OData odata, final ServiceMetadata serviceMetadata) {
        this.factory = new GenericProcessorFactory(odata, serviceMetadata, context, getCollectionService);
    }

    @Override
    public void countEntityCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
            throws ODataApplicationException, ODataLibraryException {

        GenericRequestProcessor p;
        try {
            p = factory.createProcessor(uriInfo, ContentType.TEXT_PLAIN);
            p.retrieveData(request, response, ContentType.TEXT_PLAIN);
        } catch (ODataApplicationException | ODataLibraryException e) {
            throw e;
        } catch (ODataException e) {
            throw new ODataApplicationException(e.getLocalizedMessage(),
                    HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), null, e);
        }
    }

    @Override
    public void createEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                             final ContentType requestFormat, final ContentType responseFormat)
            throws ODataApplicationException, ODataLibraryException {

    }

    @Override
    public void deleteEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
            throws ODataApplicationException, ODataLibraryException {


    }

    @Override
    public void deletePrimitive(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
            throws ODataApplicationException, ODataLibraryException {

    }

    @Override
    public void deletePrimitiveValue(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
            throws ODataApplicationException, ODataLibraryException {

    }

    @Override
    public void readEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                           final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {

        try {
            final GenericRequestProcessor p = factory.createProcessor(uriInfo, responseFormat);
            p.retrieveData(request, response, responseFormat);
        } catch (ODataApplicationException | ODataLibraryException e) {
            throw e;
        } catch (ODataException e) {
            throw new ODataApplicationException(e.getLocalizedMessage(),
                    HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), null, e);
        }

    }

    @Override
    public void readEntityCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                                     final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {

        try {
            final GenericRequestProcessor p = factory.createProcessor(uriInfo, responseFormat);
            p.retrieveData(request, response, responseFormat);
        } catch (ODataApplicationException | ODataLibraryException e) {
            throw e;
        } catch (ODataException e) {
            throw new ODataApplicationException(e.getLocalizedMessage(),
                    HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), null, e);
        }
    }

    @Override
    public void readPrimitiveCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
                                        ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
        try {
            final GenericRequestProcessor p = factory.createProcessor(uriInfo, responseFormat);
            p.retrieveData(request, response, responseFormat);
        } catch (ODataApplicationException | ODataLibraryException e) {
            throw e;
        } catch (ODataException e) {
            throw new ODataApplicationException(e.getLocalizedMessage(),
                    HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), null, e);
        }

    }

    @Override
    public void readPrimitive(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                              final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {

        try {
            final GenericRequestProcessor p = factory.createProcessor(uriInfo, responseFormat);
            p.retrieveData(request, response, responseFormat);
        } catch (ODataApplicationException | ODataLibraryException e) {
            throw e;
        } catch (ODataException e) {
            throw new ODataApplicationException(e.getLocalizedMessage(),
                    HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), null, e);
        }
    }

    @Override
    public void readPrimitiveValue(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                                   final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {

        try {
            final GenericRequestProcessor p = factory.createProcessor(uriInfo, responseFormat);
            p.retrieveData(request, response, responseFormat);
        } catch (ODataApplicationException | ODataLibraryException e) {
            throw e;
        } catch (ODataException e) {
            throw new ODataApplicationException(e.getLocalizedMessage(),
                    HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), null, e);
        }

    }



    @Override
    public void updateEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                             final ContentType requestFormat, final ContentType responseFormat)
            throws ODataApplicationException, ODataLibraryException {


    }

    @Override
    public void updatePrimitive(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                                final ContentType requestFormat, final ContentType responseFormat)
            throws ODataApplicationException, ODataLibraryException {

    }

    @Override
    public void updatePrimitiveValue(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
                                     final ContentType requestFormat, final ContentType responseFormat)
            throws ODataApplicationException, ODataLibraryException {
    }

    @Override
    public void updatePrimitiveCollection(final ODataRequest request, final ODataResponse response,
                                          final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
            throws ODataApplicationException, ODataLibraryException {
    }

    @Override
    public void deletePrimitiveCollection(final ODataRequest request, final ODataResponse response,
                                          final UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
    }
}
